package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"

	"natproxy/pkg/common"
	"natproxy/pkg/tunnel"
)

// Config 结构体用于解析配置文件
type Config struct {
	Client struct {
		ServerAddr            string `json:"server_addr"`
		LocalPort             int    `json:"local_port"`
		ClientID              string `json:"client_id"`
		HeartbeatInterval     int    `json:"heartbeat_interval"`
		MaxRetryCount         int    `json:"max_retry_count"`
		RetryInterval         int    `json:"retry_interval"`
		MaxConcurrentRequests int    `json:"max_concurrent_requests"`
		AsyncTaskWorkers      int    `json:"async_task_workers"`
		ConfigAPort           int    `json:"config_api_port"`
		UploadDir             string `json:"upload_dir"` // 添加上传目录配置
	} `json:"client"`
}

// loadConfig 加载配置文件
func loadConfig(filename string) (*Config, error) {
	// 尝试多个可能的配置文件位置
	possiblePaths := []string{
		filename,                // 当前目录
		"../../" + filename,     // 项目根目录 (当在 cmd/client 下运行时)
		"../config/config.json", // 相对于 cmd/client 的路径
		"config/config.json",    // 相对于项目根目录的路径
	}

	var configFile []byte
	var err error
	var loadedPath string

	// 尝试所有可能的路径
	for _, path := range possiblePaths {
		configFile, err = os.ReadFile(path)
		if err == nil {
			loadedPath = path
			break
		}
	}

	if err != nil {
		return nil, fmt.Errorf("无法找到配置文件，尝试过以下路径: %v", possiblePaths)
	}

	var config Config
	if err := json.Unmarshal(configFile, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件 %s 失败: %v", loadedPath, err)
	}

	log.Printf("成功加载配置文件: %s", loadedPath)
	return &config, nil
}

type Client struct {
	config         *Config
	tunnel         *tunnel.Tunnel
	connected      bool
	connecting     bool // 添加连接中的状态标记
	done           chan struct{}
	connMux        sync.RWMutex
	responseLogger *ResponseLogManager
	asyncManager   *common.AsyncTaskManager
	logger         *common.LogManager
	lastHeartbeat  time.Time
	heartbeatMux   sync.RWMutex
	heartbeatTimer *time.Timer
	fileManager    *FileManager
	fileManagerMu  sync.RWMutex // 添加锁来保护 fileManager
}

// NewClient 创建新的客户端实例
func NewClient(config *Config) *Client {
	// 创建日志配置
	logConfig := &common.LogConfig{
		ConsoleLevel:  "error",
		RetentionDays: 7,
		FileLogs: []common.FileLog{
			{
				Type:    common.LogTypeError,
				Path:    "logs/client/error",
				MaxSize: 10 * 1024 * 1024,
			},
		},
	}

	// 创建日志管理器
	logger, err := common.NewLogManager(logConfig, common.LogTypeError)
	if err != nil {
		log.Fatal("创建日志管理器失败:", err)
	}

	client := &Client{
		config:         config,
		done:           make(chan struct{}),
		responseLogger: NewResponseLogManager(),
		asyncManager:   common.NewAsyncTaskManager(config.Client.AsyncTaskWorkers),
		logger:         logger,
		lastHeartbeat:  time.Now(),
	}

	// 启动连接监控
	go client.monitorConnection()

	// 启动异步任务
	go client.asyncRoutine()

	return client
}

// 停止客户端
func (c *Client) Stop() {
	close(c.done)
	c.asyncManager.Shutdown(30 * time.Second) // 等待异步任务完成
	if c.tunnel != nil {
		c.tunnel.Close()
	}
	c.logger.Log(common.LogInfo, "客户端已停止")
}

// 添加日志管理相关的常量和结构体
const (
	MaxLogLines = 5000 // 单个日志文件最大行数
)

type LogManager struct {
	currentFile    *os.File
	currentLines   int
	currentLogDate string
	baseLogDir     string // 基础日志目录
	currentLogDir  string // 当前日期的日志目录
	mu             sync.Mutex
}

// 创建新的日志管理器
func NewLogManager(baseLogDir string) (*LogManager, error) {
	if err := os.MkdirAll(baseLogDir, 0755); err != nil {
		return nil, fmt.Errorf("创建基础日志目录失败: %v", err)
	}

	manager := &LogManager{
		baseLogDir: baseLogDir,
	}

	if err := manager.rotateIfNeeded(); err != nil {
		return nil, err
	}

	return manager, nil
}

// 检查并执行日志轮转
func (lm *LogManager) rotateIfNeeded() error {
	today := time.Now().Format("2006-01-02")

	// 如果是新的一天或者行数超过限制，需要轮转
	if lm.currentFile == nil || today != lm.currentLogDate || lm.currentLines >= MaxLogLines {
		// 确保当天的日志目录存在
		todayLogDir := filepath.Join(lm.baseLogDir, today)
		if err := os.MkdirAll(todayLogDir, 0755); err != nil {
			return fmt.Errorf("创建日期目录失败: %v", err)
		}

		// 如果当前文件存在且行数达到限制，移动到新文件
		if lm.currentFile != nil && lm.currentLines >= MaxLogLines {
			lm.currentFile.Close()

			// 生成新的文件名（使用时间戳）
			timestamp := time.Now().Format("150405") // HHMMSS
			newFileName := fmt.Sprintf("client_%s.log", timestamp)
			newPath := filepath.Join(lm.currentLogDir, newFileName)

			// 移动当前文件
			oldPath := filepath.Join(lm.currentLogDir, "client.log")
			if err := os.Rename(oldPath, newPath); err != nil {
				return fmt.Errorf("移动日志文件失败: %v", err)
			}
		}

		// 更新当前日志目录
		lm.currentLogDir = todayLogDir

		// 打开新的日志文件
		newFile, err := os.OpenFile(
			filepath.Join(lm.currentLogDir, "client.log"),
			os.O_CREATE|os.O_APPEND|os.O_WRONLY,
			0644,
		)
		if err != nil {
			return fmt.Errorf("创建新日志文件失败: %v", err)
		}

		// 关闭旧文件
		if lm.currentFile != nil {
			lm.currentFile.Close()
		}

		lm.currentFile = newFile
		lm.currentLogDate = today
		lm.currentLines = 0

		// 计算当前文件的行数
		if lines, err := lm.countFileLines(newFile.Name()); err == nil {
			lm.currentLines = lines
		}

		// 清理旧日志
		go lm.cleanOldLogs()
	}

	return nil
}

// 清理旧日志
func (lm *LogManager) cleanOldLogs() {
	// 读取日志根目录
	entries, err := os.ReadDir(lm.baseLogDir)
	if err != nil {
		log.Printf("读取日志目录失败: %v", err)
		return
	}

	// 获取7天前的日期
	cutoff := time.Now().AddDate(0, 0, -7)

	// 遍历所有日期目录
	for _, entry := range entries {
		if !entry.IsDir() {
			continue
		}

		// 解析目录名称为日期
		dirDate, err := time.Parse("2006-01-02", entry.Name())
		if err != nil {
			continue // 跳过无法解析的目录名
		}

		// 如果目录早于截止日期，删除它
		if dirDate.Before(cutoff) {
			dirPath := filepath.Join(lm.baseLogDir, entry.Name())
			if err := os.RemoveAll(dirPath); err != nil {
				log.Printf("删除旧日志目录失败 %s: %v", dirPath, err)
			} else {
				log.Printf("已删除旧日志目录: %s", dirPath)
			}
		}
	}
}

// 写入日志
func (lm *LogManager) Write(p []byte) (n int, err error) {
	lm.mu.Lock()
	defer lm.mu.Unlock()

	// 检查是否需要轮转
	if err := lm.rotateIfNeeded(); err != nil {
		return 0, err
	}

	n, err = lm.currentFile.Write(p)
	if err != nil {
		return n, err
	}

	// 计算新行数
	newLines := bytes.Count(p, []byte{'\n'})
	lm.currentLines += newLines

	return n, nil
}

// 计算文件行数
func (lm *LogManager) countFileLines(filename string) (int, error) {
	file, err := os.Open(filename)
	if err != nil {
		return 0, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	lineCount := 0
	for scanner.Scan() {
		lineCount++
	}
	return lineCount, scanner.Err()
}

// 修改 init 函数中的日志设置
func init() {
	// 获取当前工作目录
	cwd, err := os.Getwd()
	if err != nil {
		log.Fatal("获取工作目录失败:", err)
	}

	// 尝试创建日志目录
	logDirs := []string{
		filepath.Join(cwd, "logs"),
		filepath.Join(cwd, "..", "..", "logs"),
		filepath.Join(cwd, "cmd", "client", "logs"),
	}

	var logDir string
	for _, dir := range logDirs {
		if err := os.MkdirAll(dir, 0755); err == nil {
			logDir = dir
			break
		}
	}

	if logDir == "" {
		log.Fatal("无法创建日志目录")
	}

	// 创建日志管理器
	logManager, err := NewLogManager(logDir)
	if err != nil {
		log.Fatal("创建日志管理器失败:", err)
	}

	// 设置日志输出到文件和控制台
	log.SetOutput(io.MultiWriter(os.Stdout, logManager))

	// 设置日志格式
	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)

	// 打印版本信息
	log.Printf("NAT Proxy Client Version: %s (Build: %s)", Version, BuildTime)
}

func (c *Client) connect() error {
	c.connMux.Lock()
	defer c.connMux.Unlock()

	// 如果已经连接，先关闭旧连接
	if c.tunnel != nil {
		c.tunnel.Close()
		c.tunnel = nil
	}

	fmt.Printf("[连接] 正在连接服务器: %s\n", c.config.Client.ServerAddr)

	// 建立TCP连接
	conn, err := net.DialTimeout("tcp", c.config.Client.ServerAddr, 10*time.Second)
	if err != nil {
		fmt.Printf("[错误] 连接服务器失败: %v\n", err)
		return fmt.Errorf("连接服务器失败: %v", err)
	}

	// 设置 TCP keepalive
	tcpConn := conn.(*net.TCPConn)
	tcpConn.SetKeepAlive(true)
	tcpConn.SetKeepAlivePeriod(30 * time.Second)

	// 创建隧道
	t := tunnel.NewTunnel(conn)
	c.tunnel = t

	// 更新文件管理器
	c.fileManagerMu.Lock()
	c.fileManager = NewFileManager(t)
	c.fileManagerMu.Unlock()

	// 发送注册消息
	msg := &common.TunnelMessage{
		Type:   common.TypeRegister,
		Target: c.config.Client.ClientID,
	}

	if err := t.SendMessage(msg); err != nil {
		t.Close()
		c.tunnel = nil
		fmt.Printf("[错误] 发送注册消息失败: %v\n", err)
		return fmt.Errorf("发送注册消息失败: %v", err)
	}

	c.connected = true
	c.updateHeartbeat()

	fmt.Printf("[连接] 已成功连接到服务器\n")

	// 启动消息处理
	go c.handleMessages()

	return nil
}

func (c *Client) handleLocalRequest(req *common.HTTPRequest) (*common.HTTPResponse, error) {
	// 打印请求详情
	log.Printf("收到转发请求:")
	log.Printf("  Method: %s", req.Method)
	log.Printf("  Path: %s", req.Path)
	log.Printf("  Headers: %v", req.Headers)

	// 创建本地HTTP请求
	httpReq, err := http.NewRequest(
		req.Method,
		"http://localhost:"+strconv.Itoa(c.config.Client.LocalPort)+req.Path,
		bytes.NewReader(req.Body),
	)
	if err != nil {
		log.Printf("创建本地请求失败: %v", err)
		resp := common.NewStandardResponse(500, "创建本地请求失败", "服务异常")
		respBytes, _ := json.Marshal(resp)
		return &common.HTTPResponse{
			RequestID:  req.RequestID,
			StatusCode: http.StatusOK,
			Headers:    map[string]string{"Content-Type": "application/json; charset=utf-8"},
			Body:       respBytes,
		}, nil
	}

	// 设置请求头
	for k, v := range req.Headers {
		httpReq.Header.Set(k, v)
	}

	log.Printf("转发请求到本地服务: %s", httpReq.URL)

	// 发送请求
	client := &http.Client{
		Timeout: 30 * time.Second, //
	}
	resp, err := client.Do(httpReq)
	if err != nil {
		log.Printf("发送本地请求失败: %v", err)
		var errResp *common.StandardResponse
		if netErr, ok := err.(*net.OpError); ok && netErr.Op == "dial" {
			errResp = common.NewStandardResponse(503, "本地服务未启动或无法访问", "服务异常")
		} else {
			errResp = common.NewStandardResponse(502, "请求本地服务失败", "服务异常")
		}
		respBytes, _ := json.Marshal(errResp)
		return &common.HTTPResponse{
			RequestID:  req.RequestID,
			StatusCode: http.StatusOK,
			Headers:    map[string]string{"Content-Type": "application/json; charset=utf-8"},
			Body:       respBytes,
		}, nil
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Printf("读取响应体失败: %v", err)
		errResp := common.NewStandardResponse(500, "读取响应失败", "服务异常")
		respBytes, _ := json.Marshal(errResp)

		// 记录错误响应日志
		c.logResponse(req, &common.HTTPResponse{
			RequestID:  req.RequestID,
			StatusCode: http.StatusOK,
			Headers:    map[string]string{"Content-Type": "application/json; charset=utf-8"},
			Body:       respBytes,
		})

		return &common.HTTPResponse{
			RequestID:  req.RequestID,
			StatusCode: http.StatusOK,
			Headers:    map[string]string{"Content-Type": "application/json; charset=utf-8"},
			Body:       respBytes,
		}, nil
	}

	// 如果是成功的响应，直接返回原始内容
	if resp.StatusCode == http.StatusOK {
		headers := make(map[string]string)
		for k, v := range resp.Header {
			headers[k] = v[0]
		}
		response := &common.HTTPResponse{
			RequestID:  req.RequestID,
			StatusCode: resp.StatusCode,
			Headers:    headers,
			Body:       body,
		}

		// 记录成功响应日志
		c.logResponse(req, response)

		return response, nil
	}

	// 如果是错误响应，返回标准错误响应
	errResp := common.NewStandardResponse(resp.StatusCode, "服务端返回错误", "服务异常")
	respBytes, _ := json.Marshal(errResp)
	response := &common.HTTPResponse{
		RequestID:  req.RequestID,
		StatusCode: http.StatusOK,
		Headers:    map[string]string{"Content-Type": "application/json; charset=utf-8"},
		Body:       respBytes,
	}

	// 记录错误响应日志
	c.logResponse(req, response)

	return response, nil
}

// 添加响应日志记录方法
func (c *Client) logResponse(req *common.HTTPRequest, resp *common.HTTPResponse) {
	c.responseLogger.LogResponse(req.RequestID, resp)
}

func (c *Client) run() {
	heartbeatTicker := time.NewTicker(time.Duration(c.config.Client.HeartbeatInterval) * time.Second)
	defer heartbeatTicker.Stop()

	checkTicker := time.NewTicker(5 * time.Second)
	defer checkTicker.Stop()

	for {
		select {
		case <-c.done:
			return
		case <-heartbeatTicker.C:
			if err := c.sendHeartbeat(); err != nil {
				c.logger.Log(common.LogError, "发送心跳失败: %v", err)
				c.checkHeartbeat()
			}
		case <-checkTicker.C:
			c.checkHeartbeat()
		default:
			c.connMux.RLock()
			tunnel := c.tunnel
			c.connMux.RUnlock()

			if tunnel == nil {
				time.Sleep(time.Second)
				continue
			}

			msg, err := tunnel.ReadMessage()
			if err != nil {
				c.logger.Log(common.LogError, "读取消息失败: %v", err)
				c.reconnect()
				continue
			}

			switch msg.Type {
			case common.TypeHeartbeat:
				c.handleHeartbeat()
			case common.TypeHTTPRequest:
				go func(m *common.TunnelMessage) {
					defer func() {
						if r := recover(); r != nil {
							fmt.Printf("[错误] 处理请求时发生panic: %v\n", r)
						}
					}()
					c.handleRequest(m)
				}(msg)
			}
		}
	}
}

func (c *Client) reconnect() {
	// 防止重复重连
	if c.isConnecting() {
		return
	}

	c.setConnecting(true)
	defer c.setConnecting(false)

	fmt.Printf("[重连] 开始尝试重新连接服务器...\n")

	for i := 0; i < c.config.Client.MaxRetryCount; i++ {
		if c.IsConnected() {
			return
		}

		fmt.Printf("[重连] 第 %d 次尝试...\n", i+1)
		err := c.connect()
		if err == nil {
			fmt.Printf("[重连] 重连成功!\n")
			return
		}

		fmt.Printf("[重连] 失败: %v\n", err)

		// 检查是否需要继续重试
		select {
		case <-c.done:
			return
		case <-time.After(time.Duration(c.config.Client.RetryInterval) * time.Second):
			continue
		}
	}

	fmt.Printf("[重连] 达到最大重试次数，停止重连\n")
}

func (c *Client) checkStatus() {
	c.connMux.RLock()
	tunnel := c.tunnel
	c.connMux.RUnlock()

	if tunnel == nil || !tunnel.IsConnected() {
		c.logger.Log(common.LogWarn, "[状态] 检测到连接断开，尝试重连")
		go c.reconnect()
	}
}

func (c *Client) IsConnected() bool {
	c.connMux.RLock()
	defer c.connMux.RUnlock()
	return c.connected && c.tunnel != nil && c.tunnel.IsConnected()
}

func (c *Client) setConnected(status bool) {
	c.connMux.Lock()
	defer c.connMux.Unlock()
	c.connected = status
}

var (
	Version   = "dev"
	BuildTime = "unknown"
)

// ResponseLogManager 响应日志管理器
type ResponseLogManager struct {
	mu sync.Mutex
}

// NewResponseLogManager 创建响应日志管理器
func NewResponseLogManager() *ResponseLogManager {
	return &ResponseLogManager{}
}

// LogResponse 记录响应
func (rlm *ResponseLogManager) LogResponse(requestID string, response *common.HTTPResponse) {
	rlm.mu.Lock()
	defer rlm.mu.Unlock()

	// 记录响应信息
	log.Printf("[Response] RequestID: %s, Status: %d, Body Length: %d",
		requestID, response.StatusCode, len(response.Body))
}

// 异步处理例行任务
func (c *Client) asyncRoutine() {
	// 心跳检查
	c.asyncManager.Execute(func() {
		for {
			select {
			case <-c.done:
				return
			case <-time.After(time.Duration(c.config.Client.HeartbeatInterval) * time.Second):
				if err := c.sendHeartbeat(); err != nil {
					c.logger.Log(common.LogError, "[心跳] 发送失败: %v", err)
					// 如果心跳失败，触发重连
					go c.reconnect()
					return
				}
			}
		}
	})

	// 状态检查
	c.asyncManager.Execute(func() {
		for {
			select {
			case <-c.done:
				return
			case <-time.After(5 * time.Second):
				c.checkStatus()
			}
		}
	})

	// 日志清理
	c.asyncManager.Execute(func() {
		for {
			select {
			case <-c.done:
				return
			case <-time.After(time.Hour):
				c.cleanupLogs()
			}
		}
	})
}

func (c *Client) sendHeartbeat() error {
	c.connMux.RLock()
	tunnel := c.tunnel
	c.connMux.RUnlock()

	if tunnel == nil {
		return fmt.Errorf("隧道连接未建立")
	}

	if !tunnel.IsConnected() {
		return fmt.Errorf("隧道连接已断开")
	}

	return tunnel.SendMessage(&common.TunnelMessage{
		Type: common.TypeHeartbeat,
	})
}

func main() {
	// 加载配置
	config, err := loadConfig("config/config.json")
	if err != nil {
		log.Fatalf("加载配置文件失败: %v", err)
	}

	// 创建客户端实例
	client := NewClient(config)

	// 创建配置 API
	configAPI := NewConfigAPI()
	configAPI.config = config // 设置配置

	// 启动配置服务
	go func() {
		port := config.Client.ConfigAPort
		if port == 0 {
			port = 9999 // 默认端口
		}
		if err := configAPI.Start(port); err != nil {
			client.logger.Log(common.LogError, "[配置API] 启动失败: %v", err)
		}
	}()

	// 连接服务器
	if err := client.connect(); err != nil {
		log.Fatalf("连接服务器失败: %v", err)
	}

	// 启动客户端运行
	go client.run()

	// 等待信号
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	<-sigChan

	// 优雅关闭
	client.Stop()
	configAPI.Stop()
}

// 优化日志输出的方法
func (c *Client) logConnectionStatus(status string, err error) {
	if err != nil {
		c.logger.Log(common.LogError, "[连接状态] %s: %v", status, err)
	} else {
		c.logger.Log(common.LogInfo, "[连接状态] %s", status)
	}
}

// 优化心跳相关的日志
func (c *Client) handleHeartbeat() {
	c.updateHeartbeat()
	c.logger.Log(common.LogDebug, "[心跳] 收到服务器心跳响应")
}

// 修改 handleRequest 方法，添加连接检查
func (c *Client) handleRequest(msg *common.TunnelMessage) {
	// 检查连接状态
	c.connMux.RLock()
	tunnel := c.tunnel
	c.connMux.RUnlock()

	if tunnel == nil {
		fmt.Printf("[错误] 无法处理请求：连接已断开\n")
		return
	}

	var httpReq common.HTTPRequest
	if err := json.Unmarshal(msg.Payload, &httpReq); err != nil {
		fmt.Printf("[错误] 解析HTTP请求失败: %v\n", err)
		c.sendErrorResponseSafe(msg.RequestID, fmt.Errorf("invalid request format"))
		return
	}

	// 处理文件上传请求
	if httpReq.Method == "POST" && strings.HasPrefix(httpReq.Path, "/api/files/upload") {
		c.handleFileUpload(&httpReq, msg.RequestID)
		return
	}

	// 打印请求信息
	fmt.Printf("[请求] 收到HTTP请求: %s %s\n", httpReq.Method, httpReq.Path)

	// 构造本地请求地址
	localAddr := fmt.Sprintf("http://localhost:%d%s",
		c.config.Client.LocalPort, httpReq.Path)

	// 创建HTTP请求
	req, err := http.NewRequest(httpReq.Method, localAddr, bytes.NewReader(httpReq.Body))
	if err != nil {
		fmt.Printf("[错误] 创建本地请求失败: %v\n", err)
		c.sendErrorResponseSafe(msg.RequestID, fmt.Errorf("create request failed"))
		return
	}

	// 复制请求头
	for k, v := range httpReq.Headers {
		req.Header.Set(k, v)
	}

	// 发送请求
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Printf("[错误] 发送本地请求失败: %v\n", err)
		c.sendErrorResponseSafe(msg.RequestID, fmt.Errorf("local request failed"))
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("[错误] 读取响应体失败: %v\n", err)
		c.sendErrorResponseSafe(msg.RequestID, fmt.Errorf("read response failed"))
		return
	}

	// 构造响应
	httpResp := &common.HTTPResponse{
		RequestID:  msg.RequestID,
		StatusCode: resp.StatusCode,
		Headers:    make(map[string]string),
		Body:       body,
	}

	// 复制响应头
	for k, v := range resp.Header {
		if len(v) > 0 {
			httpResp.Headers[k] = v[0]
		}
	}

	// 发送响应
	if err := c.sendResponseSafe(msg.RequestID, httpResp); err != nil {
		fmt.Printf("[错误] 发送响应失败: %v\n", err)
	} else {
		fmt.Printf("[响应] 成功发送响应: %d %s\n", resp.StatusCode, resp.Status)
	}
}

// 添加安全的响应发送方法
func (c *Client) sendResponseSafe(requestID string, resp *common.HTTPResponse) error {
	c.connMux.RLock()
	tunnel := c.tunnel
	c.connMux.RUnlock()

	if tunnel == nil {
		return fmt.Errorf("connection is closed")
	}

	respBytes, err := json.Marshal(resp)
	if err != nil {
		return fmt.Errorf("marshal response failed: %v", err)
	}

	return tunnel.SendMessage(&common.TunnelMessage{
		Type:      common.TypeHTTPResponse,
		RequestID: requestID,
		Payload:   respBytes,
	})
}

// 添加安全的错误响应发送方法
func (c *Client) sendErrorResponseSafe(requestID string, err error) {
	resp := &common.HTTPResponse{
		StatusCode: http.StatusBadRequest,
		Headers: map[string]string{
			"Content-Type": "application/json",
			"X-Error":      err.Error(),
		},
		Body: []byte(fmt.Sprintf(`{
			"code": 400,
			"message": "%s",
			"error": true
		}`, err.Error())),
	}

	if sendErr := c.sendResponseSafe(requestID, resp); sendErr != nil {
		fmt.Printf("[错误] 发送错误响应失败: %v\n", sendErr)
	}
}

// 添加 MultipartFile 结构体
type MultipartFile struct {
	FileID      string `json:"file_id"`
	FileName    string `json:"file_name"`
	ContentType string `json:"content_type"`
	ChunkIndex  int    `json:"chunk_index"`
	TotalChunks int    `json:"total_chunks"`
	MD5         string `json:"md5"`
	Data        []byte `json:"data"`
}

// 处理文件上传
func (c *Client) handleFileUpload(req *common.HTTPRequest, requestID string) {
	// 构造本地请求地址
	localAddr := fmt.Sprintf("http://localhost:%d%s",
		c.config.Client.LocalPort, req.Path)

	// 创建HTTP请求
	httpReq, err := http.NewRequest(req.Method, localAddr, bytes.NewReader(req.Body))
	if err != nil {
		fmt.Printf("[错误] 创建本地请求失败: %v\n", err)
		c.sendErrorResponse(requestID, fmt.Errorf("create request failed: %v", err))
		return
	}

	// 复制请求头
	for k, v := range req.Headers {
		httpReq.Header.Set(k, v)
	}

	// 发送请求
	client := &http.Client{
		Timeout: 30 * time.Minute, // 设置较长的超时时间，因为是文件上传
	}

	resp, err := client.Do(httpReq)
	if err != nil {
		fmt.Printf("[错误] 发送本地请求失败: %v\n", err)
		c.sendErrorResponse(requestID, fmt.Errorf("local request failed: %v", err))
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("[错误] 读取响应体失败: %v\n", err)
		c.sendErrorResponse(requestID, fmt.Errorf("read response failed: %v", err))
		return
	}

	// 构造响应
	httpResp := &common.HTTPResponse{
		StatusCode: resp.StatusCode,
		Headers:    make(map[string]string),
		Body:       body,
	}

	// 复制响应头
	for k, v := range resp.Header {
		if len(v) > 0 {
			httpResp.Headers[k] = v[0]
		}
	}

	// 发送响应
	respBytes, err := json.Marshal(httpResp)
	if err != nil {
		fmt.Printf("[错误] 序列化响应失败: %v\n", err)
		c.sendErrorResponse(requestID, fmt.Errorf("marshal response failed: %v", err))
		return
	}

	err = c.tunnel.SendMessage(&common.TunnelMessage{
		Type:      common.TypeHTTPResponse,
		RequestID: requestID,
		Payload:   respBytes,
	})

	if err != nil {
		fmt.Printf("[错误] 发送响应失败: %v\n", err)
	} else {
		fmt.Printf("[响应] 成功转发文件上传响应: %d\n", resp.StatusCode)
	}
}

// 修改发送错误响应的方法
func (c *Client) sendErrorResponse(requestID string, err error) {
	resp := &common.HTTPResponse{
		StatusCode: http.StatusBadRequest, // 使用 400 状态码表示请求格式错误
		Headers: map[string]string{
			"Content-Type": "application/json",
			"X-Error":      err.Error(),
		},
		Body: []byte(fmt.Sprintf(`{
			"code": 400,
			"message": "%s",
			"error": true
		}`, err.Error())),
	}
	c.sendResponse(requestID, resp)
}

// 修改发送成功响应的方法
func (c *Client) sendSuccessResponse(requestID string, status tunnel.FileTransferStatus) {
	resp := &common.HTTPResponse{
		StatusCode: http.StatusOK,
		Headers: map[string]string{
			"Content-Type": "application/json",
		},
		Body: []byte(fmt.Sprintf(`{
			"code": 200,
			"message": "success",
			"data": {
				"file_id": "%s",
				"total_size": %d,
				"chunks": %d,
				"completed": true
			}
		}`, status.FileID, status.TotalSize, status.TotalChunks)),
	}
	c.sendResponse(requestID, resp)
}

// 发送响应
func (c *Client) sendResponse(requestID string, resp *common.HTTPResponse) {
	respBytes, _ := json.Marshal(resp)
	err := c.tunnel.SendMessage(&common.TunnelMessage{
		Type:      common.TypeHTTPResponse,
		RequestID: requestID,
		Payload:   respBytes,
	})
	if err != nil {
		fmt.Printf("[错误] 发送响应失败: %v\n", err)
	}
}

// 优化连接状态监控的日志
func (c *Client) checkHeartbeat() {
	c.heartbeatMux.RLock()
	lastBeat := c.lastHeartbeat
	c.heartbeatMux.RUnlock()

	timeSinceLastBeat := time.Since(lastBeat)
	maxInterval := time.Duration(c.config.Client.HeartbeatInterval*2) * time.Second

	if timeSinceLastBeat > maxInterval {
		c.logger.Log(common.LogWarn, "[心跳] 超时 (最后心跳: %v 前)", timeSinceLastBeat.Round(time.Second))
		c.reconnect()
	}
}

func (c *Client) updateHeartbeat() {
	c.heartbeatMux.Lock()
	c.lastHeartbeat = time.Now()
	c.heartbeatMux.Unlock()
}

func (c *Client) cleanupLogs() {
	// 清理过期日志文件
	cutoff := time.Now().AddDate(0, 0, -7) // 保留7天的日志
	if err := c.logger.Cleanup(cutoff); err != nil {
		c.logger.Log(common.LogError, "清理日志失败: %v", err)
	}
}

func (c *Client) monitorConnection() {
	ticker := time.NewTicker(time.Minute)
	defer ticker.Stop()

	for {
		select {
		case <-c.done:
			return
		case <-ticker.C:
			c.checkStatus()
		}
	}
}

// 添加消息处理方法
func (c *Client) handleMessages() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("[错误] 消息处理发生panic: %v\n", r)
		}
	}()

	for {
		select {
		case <-c.done:
			return
		default:
			if !c.IsConnected() {
				fmt.Printf("[连接] 连接已断开，等待重连...\n")
				time.Sleep(time.Second * 5)
				continue
			}

			msg, err := c.tunnel.ReadMessage()
			if err != nil {
				if err != io.EOF && !strings.Contains(err.Error(), "connection is closed") {
					fmt.Printf("[错误] 读取消息失败: %v\n", err)
				}
				c.setConnected(false)
				if !c.isConnecting() {
					go c.reconnect()
				}
				return
			}

			// 更新心跳时间
			c.updateHeartbeat()

			// 处理消息
			switch msg.Type {
			case common.TypeHeartbeat:
				fmt.Printf("[心跳] 收到服务器心跳\n")
				c.handleHeartbeat()
			case common.TypeHTTPRequest:
				go c.handleRequest(msg)
			default:
				fmt.Printf("[警告] 收到未知类型的消息: %v\n", msg.Type)
			}
		}
	}
}

// 添加连接状态检查方法
func (c *Client) isConnecting() bool {
	c.connMux.RLock()
	defer c.connMux.RUnlock()
	return c.connecting
}

func (c *Client) setConnecting(status bool) {
	c.connMux.Lock()
	defer c.connMux.Unlock()
	c.connecting = status
}

// 添加文件传输管理器
type FileManager struct {
	transfers sync.Map
	tunnel    *tunnel.Tunnel
	mu        sync.RWMutex // 添加锁来保护 tunnel
}

// FileTransfer 表示单个文件传输任务
type FileTransfer struct {
	Status    tunnel.FileTransferStatus
	Done      chan struct{}
	Error     error
	StartTime time.Time
}

// 初始化文件管理器
func NewFileManager(t *tunnel.Tunnel) *FileManager {
	return &FileManager{
		tunnel: t,
	}
}

// StartFileTransfer 开始文件传输
func (fm *FileManager) StartFileTransfer(fileID, filePath string) (*FileTransfer, error) {
	fm.mu.RLock()
	t := fm.tunnel
	fm.mu.RUnlock()

	if t == nil {
		return nil, fmt.Errorf("tunnel connection not available")
	}

	// 检查文件是否存在
	if _, err := os.Stat(filePath); err != nil {
		return nil, fmt.Errorf("file not found: %v", err)
	}

	// 创建传输任务
	transfer := &FileTransfer{
		Done:      make(chan struct{}),
		StartTime: time.Now(),
	}

	// 存储传输任务
	fm.transfers.Store(fileID, transfer)

	// 创建进度通道
	progressChan := make(chan tunnel.FileTransferStatus, 100)

	// 启动传输协程
	go func() {
		defer close(transfer.Done)
		defer close(progressChan)
		defer fm.transfers.Delete(fileID)

		// 再次检查隧道连接
		fm.mu.RLock()
		t = fm.tunnel
		fm.mu.RUnlock()

		if t == nil {
			transfer.Error = fmt.Errorf("tunnel connection lost")
			return
		}

		// 开始传输
		err := t.SendFile(fileID, filePath, progressChan)
		if err != nil {
			transfer.Error = err
			fmt.Printf("[文件] 传输失败 %s: %v\n", fileID, err)
			return
		}

		// 监听进度
		for status := range progressChan {
			transfer.Status = status
			progress := float64(status.CurrentChunk) / float64(status.TotalChunks) * 100
			fmt.Printf("[文件] 传输进度 %s: %.2f%% (%d/%d)\n",
				fileID, progress, status.CurrentChunk, status.TotalChunks)
		}

		fmt.Printf("[文件] 传输完成 %s: %d bytes\n", fileID, transfer.Status.TotalSize)
	}()

	return transfer, nil
}

// GetTransferStatus 获取传输状态
func (fm *FileManager) GetTransferStatus(fileID string) (*FileTransfer, bool) {
	if value, ok := fm.transfers.Load(fileID); ok {
		return value.(*FileTransfer), true
	}
	return nil, false
}
